// src/main/index.js

const { app, shell, BrowserWindow, ipcMain, dialog } = require('electron')
const path = require('path')
const { join } = require('path')
const { electronApp, optimizer, is } = require('@electron-toolkit/utils')
const { fileManager, permissionManager } = require('./utils')
const projectManager = require('./utils/projectManager')

process.on('uncaughtException', (err) => {
  console.error('未捕获异常:', err);
  console.error('错误堆栈:', err.stack);
  console.error('进程信息:', process.pid);
});

process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的Promise拒绝:', reason);
  console.error('Promise对象:', promise);
  console.error('进程信息:', process.pid);
});

/**
 * 创建浏览器窗口
 */
function createWindow() {
  // 窗口
  const mainWindow = new BrowserWindow({
    width: 1920,
    height: 1080,
    show: false,
    autoHideMenuBar: true,
    webPreferences: {
      // 预加载脚本，建立主进程与渲染进程的通信桥梁 [cite: 32]
      preload: path.join(__dirname, 'preload.js'),
      // 出于安全考虑，禁用沙箱以在预加载脚本中使用 Node.js 模块
      sandbox: false,
      // 启用 contextIsolation 以确保安全性
      contextIsolation: true,
      // 禁用 nodeIntegration 以确保安全性
      nodeIntegration: false
    }
  })

  // 窗口准备好后显示
  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  // 在新窗口中打开所有外部链接
  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // 根据环境加载 URL
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
    // 开发模式下自动打开开发者工具
    mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
}

// === 应用生命周期事件 ===

// Electron 初始化完成后调用
app.whenReady().then(() => {
  electronApp.setAppUserModelId('com.electron')

  // 优化浏览器窗口事件处理
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  // 创建主窗口
  createWindow()

  // macOS Dock 栏图标点击事件
  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 所有窗口关闭后退出应用 (Windows & Linux)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// === IPC 通信处理模块 ===
ipcMain.handle('start-training', async (event, trainingConfig) => {
  console.log('接收到训练请求:', trainingConfig)
  return { success: true, message: '训练任务已启动' }
})

/**
 * 处理打开图片文件的请求
 */
ipcMain.handle('dialog:openImage', async (event) => {
  console.log('[IPC] dialog:openImage 请求收到')
  try {
    const filePaths = await fileManager.openImageDialog()
    
    if (filePaths.length > 0) {
      // 检查并请求权限
      const accessibleFiles = await permissionManager.checkAndRequestPermissions(filePaths)
      console.log('[IPC] 权限检查完成，可访问文件:', accessibleFiles)
      return accessibleFiles
    }
    
    return []
  } catch (err) {
    console.error('[IPC] 打开图片对话框出错:', err)
    return []
  }
})

/**
 * 处理选择目录的请求
 */
ipcMain.handle('dialog:selectDirectory', async (event, title) => {
  console.log('[IPC] dialog:selectDirectory 请求收到，title:', title)
  try {
    const dirPath = await fileManager.openDirectoryDialog({ title })
    
    if (dirPath) {
      // 验证目录权限
      const permissionStatus = await permissionManager.validateDirectoryPermissions(dirPath)
      console.log('[IPC] 目录权限检查:', permissionStatus)
      
      if (permissionStatus.valid) {
        return dirPath
      } else {
        console.log('[IPC] 目录权限不足:', dirPath)
        return null
      }
    }
    
    return null
  } catch (err) {
    console.error('[IPC] 打开目录对话框出错:', err)
    return null
  }
})

/**
 * 处理导出标注数据的请求
 */
ipcMain.handle('dialog:exportAnnotations', async (event, annotationData) => {
  console.log('[IPC] dialog:exportAnnotations 请求收到')
  try {
    const exportPath = await fileManager.exportAnnotationData(annotationData)
    return exportPath
  } catch (err) {
    console.error('[IPC] 导出标注数据出错:', err)
    return null
  }
})

/**
 * 处理显示权限帮助的请求
 */
ipcMain.handle('dialog:showPermissionHelp', async (event) => {
  console.log('[IPC] dialog:showPermissionHelp 请求收到')
  try {
    await permissionManager.showPermissionHelp()
    return true
  } catch (err) {
    console.error('[IPC] 显示权限帮助出错:', err)
    return false
  }
})

// === 项目管理相关 IPC 处理器 ===

/**
 * 初始化项目管理器
 */
ipcMain.handle('project:initialize', async (event, workspaceDir) => {
  console.log('[IPC] project:initialize 请求收到，工作目录:', workspaceDir)
  try {
    await projectManager.initialize(workspaceDir)
    return { success: true }
  } catch (err) {
    console.error('[IPC] 初始化项目管理器出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 创建新项目
 */
ipcMain.handle('project:create', async (event, projectData) => {
  console.log('[IPC] project:create 请求收到:', projectData)
  try {
    const result = await projectManager.createProject(projectData)
    return result
  } catch (err) {
    console.error('[IPC] 创建项目出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 加载项目
 */
ipcMain.handle('project:load', async (event, projectPath) => {
  console.log('[IPC] project:load 请求收到:', projectPath)
  try {
    const result = await projectManager.loadProject(projectPath)
    return result
  } catch (err) {
    console.error('[IPC] 加载项目出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 保存项目
 */
ipcMain.handle('project:save', async (event, projectConfig) => {
  console.log('[IPC] project:save 请求收到')
  try {
    const result = await projectManager.saveProject(projectConfig)
    return result
  } catch (err) {
    console.error('[IPC] 保存项目出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 获取最近项目列表
 */
ipcMain.handle('project:getRecent', async (event) => {
  console.log('[IPC] project:getRecent 请求收到')
  try {
    const projects = await projectManager.getRecentProjects()
    return { success: true, projects }
  } catch (err) {
    console.error('[IPC] 获取最近项目出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 导入图像到项目
 */
ipcMain.handle('project:importImages', async (event, projectPath, imagePaths) => {
  console.log('[IPC] project:importImages 请求收到')
  try {
    const result = await projectManager.importImages(projectPath, imagePaths)
    return result
  } catch (err) {
    console.error('[IPC] 导入图像出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 处理获取本地方法配置的请求
 */
ipcMain.handle('project:getLocalMethods', async (event) => {
  console.log('[IPC] project:getLocalMethods 请求收到')
  try {
    const result = await projectManager.getLocalMethods()
    return result
  } catch (err) {
    console.error('[IPC] 获取方法配置出错:', err)
    return { success: false, error: err.message, config: projectManager.getDefaultMethodsConfig() }
  }
})

/**
 * 删除项目
 */
ipcMain.handle('project:delete', async (event, projectPath) => {
  console.log('[IPC] project:delete 请求收到:', projectPath)
  try {
    const result = await projectManager.deleteProject(projectPath)
    return result
  } catch (err) {
    console.error('[IPC] 删除项目出错:', err)
    return { success: false, error: err.message }
  }
})


/**
 * 处理打开文件夹的请求
 */
ipcMain.handle('system:openFolder', async (event, folderPath) => {
  console.log('[IPC] system:openFolder 请求收到，路径:', folderPath)
  try {
    const { shell } = require('electron')
    await shell.openPath(folderPath)
    return { success: true }
  } catch (err) {
    console.error('[IPC] 打开文件夹出错:', err)
    return { success: false, error: err.message }
  }
})

/**
 * 处理打开文件对话框的请求
 */
ipcMain.handle('dialog:openFile', async (event, filters) => {
  console.log('[IPC] dialog:openFile 请求收到', filters)
  try {
    const result = await dialog.showOpenDialog({
      filters: filters || [
        { name: 'All Files', extensions: ['*'] }
      ],
      properties: ['openFile', 'multiSelections']
    })
    
    if (result.canceled) {
      return []
    }
    
    return result.filePaths
  } catch (err) {
    console.error('[IPC] 打开文件对话框出错:', err)
    return []
  }
})

/**
 * 保存缩略图文件
 */
ipcMain.handle('system:saveThumbnail', async (_, projectPath, fileName, base64Data) => {
  console.log('[IPC] system:saveThumbnail 请求收到:', fileName)
  try {
    const fs = require('fs').promises
    const path = require('path')
    
    // 创建thumbnails目录
    const thumbnailsDir = path.join(projectPath, 'thumbnails')
    await fs.mkdir(thumbnailsDir, { recursive: true })
    
    // 提取base64数据（移除data:image/jpeg;base64,前缀）
    const base64Content = base64Data.replace(/^data:image\/[a-z]+;base64,/, '')
    
    // 保存文件
    const filePath = path.join(thumbnailsDir, fileName)
    await fs.writeFile(filePath, base64Content, 'base64')
    
    console.log('[IPC] 缩略图保存成功:', filePath)
    return {
      success: true,
      filePath: filePath
    }
  } catch (error) {
    console.error('[IPC] 缩略图保存失败:', error)
    return {
      success: false,
      error: error.message
    }
  }
})

/**
 * 删除缩略图文件
 */
ipcMain.handle('system:deleteThumbnail', async (_, projectPath, fileName) => {
  console.log('[IPC] system:deleteThumbnail 请求收到:', fileName)
  try {
    const fs = require('fs').promises
    const path = require('path')
    
    // 构建缩略图文件路径
    const thumbnailsDir = path.join(projectPath, 'thumbnails')
    const filePath = path.join(thumbnailsDir, fileName)
    
    // 检查文件是否存在
    try {
      await fs.access(filePath)
      // 删除文件
      await fs.unlink(filePath)
      console.log('[IPC] 缩略图删除成功:', filePath)
      return {
        success: true,
        message: '缩略图文件删除成功'
      }
    } catch (accessError) {
      if (accessError.code === 'ENOENT') {
        console.log('[IPC] 缩略图文件不存在，跳过删除:', filePath)
        return {
          success: true,
          message: '缩略图文件不存在，跳过删除'
        }
      }
      throw accessError
    }
  } catch (error) {
    console.error('[IPC] 缩略图删除失败:', error)
    return {
      success: false,
      error: error.message
    }
  }
})

/**
 * 获取本地图片的base64数据
 */
ipcMain.handle('system:getLocalImageData', async (_, imagePath) => {
  console.log('[IPC] system:getLocalImageData 请求收到:', imagePath)
  console.log('[IPC] 检查文件路径类型:', typeof imagePath)
  console.log('[IPC] 检查文件路径长度:', imagePath.length)
  try {
    const fs = require('fs').promises
    const path = require('path')
    
    // 检查文件是否存在
    console.log('[IPC] 正在检查文件是否存在...')
    await fs.access(imagePath)
    console.log('[IPC] 文件存在，开始读取...')
    
    // 读取文件
    const imageBuffer = await fs.readFile(imagePath)
    
    // 获取文件扩展名来确定MIME类型
    const ext = path.extname(imagePath).toLowerCase()
    const mimeTypes = {
      '.jpg': 'image/jpeg',
      '.jpeg': 'image/jpeg', 
      '.png': 'image/png',
      '.gif': 'image/gif',
      '.bmp': 'image/bmp',
      '.webp': 'image/webp',
      '.tiff': 'image/tiff',
      '.tif': 'image/tiff'
    }
    
    const mimeType = mimeTypes[ext] || 'image/jpeg'
    const base64Data = imageBuffer.toString('base64')
    
    return {
      success: true,
      data: `data:${mimeType};base64,${base64Data}`,
      mimeType
    }
  } catch (err) {
    console.error('[IPC] 获取图片数据出错:', err)
    return {
      success: false,
      error: err.message
    }
  }
})

/**
 * 获取图片尺寸信息
 */
ipcMain.handle('system:getImageDimensions', async (_, imagePath) => {
  console.log('[IPC] system:getImageDimensions 请求收到:', imagePath)
  try {
    const fs = require('fs').promises
    
    // 检查文件是否存在
    await fs.access(imagePath)
    
    // 获取图片尺寸
    let width = null, height = null
    try {
      // 尝试使用sharp获取图片尺寸
      const sharp = require('sharp')
      const metadata = await sharp(imagePath).metadata()
      width = metadata.width
      height = metadata.height
    } catch (error) {
      // 尝试使用基础方法读取图片头部信息
      try {
        const projectManager = require('./utils/projectManager')
        const dimensions = await projectManager.getImageDimensionsBasic(imagePath)
        width = dimensions.width
        height = dimensions.height
      } catch (basicError) {
        console.warn(`[IPC] 获取图片尺寸失败: ${basicError.message}`)
      }
    }
    
    return {
      success: true,
      width,
      height,
      size: width && height ? `${width}*${height}` : '未知尺寸'
    }
  } catch (err) {
    console.error('[IPC] 获取图片尺寸出错:', err)
    return {
      success: false,
      error: err.message
    }
  }
})

/**
 * 获取文件夹中的所有图片文件
 */
ipcMain.handle('system:getImagesFromFolder', async (_, folderPath) => {
  console.log('[IPC] system:getImagesFromFolder 请求收到:', folderPath)
  try {
    const fs = require('fs').promises
    const path = require('path')
    
    // 检查文件夹是否存在
    await fs.access(folderPath)
    
    // 支持的图片扩展名
    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.tif']
    
    // 读取文件夹内容
    const files = await fs.readdir(folderPath)
    const imagePaths = []
    
    for (const file of files) {
      const filePath = path.join(folderPath, file)
      const stat = await fs.stat(filePath)
      
      // 只处理文件，不处理子目录
      if (stat.isFile()) {
        const ext = path.extname(file).toLowerCase()
        if (imageExtensions.includes(ext)) {
          imagePaths.push(filePath)
        }
      }
    }
    
    console.log(`[IPC] 在文件夹中找到 ${imagePaths.length} 张图片`)
    return imagePaths
    
  } catch (err) {
    console.error('[IPC] 获取文件夹图片出错:', err)
    return []
  }
})

/**
 * 读取文件内容
 */
ipcMain.handle('system:readFile', async (_, filePath) => {
  console.log('[IPC] system:readFile 请求收到:', filePath)
  try {
    const fs = require('fs').promises
    
    // 检查文件是否存在
    await fs.access(filePath)
    
    // 读取文件内容
    const content = await fs.readFile(filePath, 'utf8')
    
    return {
      success: true,
      content
    }
  } catch (err) {
    console.error('[IPC] 读取文件出错:', err)
    return {
      success: false,
      error: err.message
    }
  }
})